package service

import (
	"errors"
	"time"

	"gitee.com/li-zhenyi/yi-nian-zhi-jian/backend/internal/model"
	"gitee.com/li-zhenyi/yi-nian-zhi-jian/backend/internal/repository"
)

// GameService 定义游戏服务接口
// 这个接口定义了所有游戏核心业务逻辑的方法
type GameService interface {
	// 开始修炼
	StartCultivation(userID int64, duration int) (*CultivationResult, error)
	// 获取游戏状态
	GetGameStatus(userID int64) (*GameStatus, error)
	// 突破境界
	BreakthroughRealm(userID int64) (*RealmBreakthroughResult, error)
}

// CultivationResult 修炼结果结构体
type CultivationResult struct {
	CultivationGained    int64  `json:"cultivation_gained"`
	TotalCultivation     int64  `json:"total_cultivation"`
	RealmBreakthrough    bool   `json:"realm_breakthrough"`
	NewRealm             string `json:"new_realm"`
	NewRealmLevel        int    `json:"new_realm_level"`
	CultivationTime      int    `json:"cultivation_time"`
}

// GameStatus 游戏状态结构体
type GameStatus struct {
	UserInfo      *model.User       `json:"user_info"`
	OfflineGain   int64             `json:"offline_gain"`
	ActiveEvents  []map[string]interface{} `json:"active_events"`
	LastUpdate    int64             `json:"last_update"`
}

// RealmBreakthroughResult 境界突破结果结构体
type RealmBreakthroughResult struct {
	Success       bool   `json:"success"`
	NewRealm      string `json:"new_realm"`
	NewRealmLevel int    `json:"new_realm_level"`
	RemainingCultivation int64 `json:"remaining_cultivation"`
	Message       string `json:"message"`
}

// gameService 实现GameService接口
// 这个结构体封装了游戏核心业务逻辑
type gameService struct {
	userRepo repository.UserRepository
}

// NewGameService 创建一个新的游戏服务实例
// 参数userRepo是用户仓库接口，用于数据访问
func NewGameService(userRepo repository.UserRepository) GameService {
	return &gameService{userRepo: userRepo}
}

// StartCultivation 开始修炼
// 参数userID是用户ID，duration是修炼时长（小时）
// 返回修炼结果和可能的错误
func (s *gameService) StartCultivation(userID int64, duration int) (*CultivationResult, error) {
	// 参数验证
	if duration <= 0 || duration > 24 {
		return nil, errors.New("修炼时长必须在1-24小时之间")
	}

	// 获取用户信息
	user, err := s.userRepo.GetByID(userID)
	if err != nil {
		return nil, err
	}
	if user == nil {
		return nil, errors.New("用户不存在")
	}

	// 计算修炼获得的修为值
	// 基础修为增长 = 时长 * 基础速率
	baseGain := int64(duration * 10)
	// 根据根骨和悟性调整修为获得量
	talentBonus := int64(user.Talent) * baseGain / 100
	comprehensionBonus := int64(user.Comprehension) * baseGain / 100
	adjustedGain := baseGain + talentBonus + comprehensionBonus

	// 更新用户修为
	user.Cultivation += adjustedGain

	// 检查是否突破境界
	realmBreakthrough := false
	newRealm := user.Realm
	newRealmLevel := user.RealmLevel

	// 境界突破逻辑
	requiredCultivation := s.calculateRequiredCultivation(user.Realm, user.RealmLevel)
	if user.Cultivation >= requiredCultivation {
		// 自动突破境界
		breakthroughResult := s.autoBreakthrough(user)
		realmBreakthrough = breakthroughResult.Success
		newRealm = breakthroughResult.NewRealm
		newRealmLevel = breakthroughResult.NewRealmLevel
	}

	// 保存用户信息
	if err := s.userRepo.Update(user); err != nil {
		return nil, err
	}

	// 返回修炼结果
	return &CultivationResult{
		CultivationGained: adjustedGain,
		TotalCultivation:  user.Cultivation,
		RealmBreakthrough: realmBreakthrough,
		NewRealm:          newRealm,
		NewRealmLevel:     newRealmLevel,
		CultivationTime:   duration,
	}, nil
}

// GetGameStatus 获取游戏状态
// 参数userID是用户ID
// 返回游戏状态和可能的错误
func (s *gameService) GetGameStatus(userID int64) (*GameStatus, error) {
	// 获取用户信息
	user, err := s.userRepo.GetByID(userID)
	if err != nil {
		return nil, err
	}
	if user == nil {
		return nil, errors.New("用户不存在")
	}

	// 模拟计算离线收益
	// 这里应该根据最后登录时间计算，但现在简单模拟
	offlineGain := int64(120)

	// 模拟生成活跃事件
	events := []map[string]interface{}{
		{
			"id":          1,
			"type":        "opportunity",
			"title":       "神秘洞穴",
			"description": "发现一个神秘的洞穴，里面可能有宝物...",
			"expires_at":  time.Now().Add(24 * time.Hour).Unix(),
		},
		{
			"id":          2,
			"type":        "challenge",
			"title":       "妖兽来袭",
			"description": "附近出现了一只妖兽，需要立即处理！",
			"expires_at":  time.Now().Add(1 * time.Hour).Unix(),
		},
	}

	// 返回游戏状态
	return &GameStatus{
		UserInfo:     user,
		OfflineGain:  offlineGain,
		ActiveEvents: events,
		LastUpdate:   time.Now().Unix(),
	}, nil
}

// BreakthroughRealm 手动突破境界
// 参数userID是用户ID
// 返回突破结果和可能的错误
func (s *gameService) BreakthroughRealm(userID int64) (*RealmBreakthroughResult, error) {
	// 获取用户信息
	user, err := s.userRepo.GetByID(userID)
	if err != nil {
		return nil, err
	}
	if user == nil {
		return nil, errors.New("用户不存在")
	}

	// 计算突破所需修为
	requiredCultivation := s.calculateRequiredCultivation(user.Realm, user.RealmLevel)

	// 检查修为是否足够
	if user.Cultivation < requiredCultivation {
		return &RealmBreakthroughResult{
			Success:       false,
			NewRealm:      user.Realm,
			NewRealmLevel: user.RealmLevel,
			Message:       "修为不足，无法突破",
		},
		nil
	}

	// 执行突破
	breakthroughResult := s.autoBreakthrough(user)

	// 保存用户信息
	if err := s.userRepo.Update(user); err != nil {
		return nil, err
	}

	return breakthroughResult, nil
}

// calculateRequiredCultivation 计算突破所需的修为值
func (s *gameService) calculateRequiredCultivation(realm string, realmLevel int) int64 {
	// 基础突破需求
	baseRequirement := int64(1000)

	// 不同境界的突破难度系数
	realmMultiplier := 1.0
	switch realm {
	case "练气期":
		realmMultiplier = 1.0
	case "筑基期":
		realmMultiplier = 5.0
	case "结丹期":
		realmMultiplier = 10.0
	case "元婴期":
		realmMultiplier = 20.0
	case "化神期":
		realmMultiplier = 50.0
	case "炼虚期":
		realmMultiplier = 100.0
	case "合体期":
		realmMultiplier = 200.0
	case "大乘期":
		realmMultiplier = 500.0
	case "渡劫期":
		realmMultiplier = 1000.0
	case "飞升期":
		// 已达到最高境界，不需要突破
		return int64(9999999)
	}

	// 境界小层的难度系数
	subLevelMultiplier := float64(realmLevel)

	// 计算总需求
	totalRequirement := int64(float64(baseRequirement) * realmMultiplier * subLevelMultiplier)

	return totalRequirement
}

// autoBreakthrough 自动突破境界
func (s *gameService) autoBreakthrough(user *model.User) *RealmBreakthroughResult {
	// 修仙境界列表
	realms := []string{
		"练气期", "筑基期", "结丹期", "元婴期",
		"化神期", "炼虚期", "合体期", "大乘期", "渡劫期", "飞升期",
	}

	// 找到当前境界在列表中的位置
	currentRealmIndex := -1
	for i, r := range realms {
		if r == user.Realm {
			currentRealmIndex = i
			break
		}
	}

	// 已经是最高境界
	if currentRealmIndex == len(realms)-1 {
		return &RealmBreakthroughResult{
			Success:       false,
			NewRealm:      user.Realm,
			NewRealmLevel: user.RealmLevel,
			Message:       "已达到最高境界",
		}
	}

	// 计算突破所需修为
	requiredCultivation := s.calculateRequiredCultivation(user.Realm, user.RealmLevel)

	// 检查修为是否足够
	if user.Cultivation < requiredCultivation {
		return &RealmBreakthroughResult{
			Success:       false,
			NewRealm:      user.Realm,
			NewRealmLevel: user.RealmLevel,
			Message:       "修为不足，无法突破",
		}
	}

	// 扣除突破所需的修为
	user.Cultivation -= requiredCultivation

	// 尝试突破
	// 这里简单模拟突破成功率，实际游戏中应该有更复杂的机制
	successRate := 0.8 // 80%的成功率
	randomChance := float64(time.Now().UnixNano()%100) / 100

	if randomChance <= successRate {
		// 突破成功
		// 检查是否是境界小层突破还是大境界突破
		if user.RealmLevel < 3 {
			// 小层突破
			user.RealmLevel++
		} else {
			// 大境界突破
			user.RealmLevel = 1
			user.Realm = realms[currentRealmIndex+1]
		}

		// 提升属性
		s.boostAttributesAfterBreakthrough(user)

		return &RealmBreakthroughResult{
			Success:             true,
			NewRealm:            user.Realm,
			NewRealmLevel:       user.RealmLevel,
			RemainingCultivation: user.Cultivation,
			Message:             "突破成功！恭喜你踏入了新的境界！",
		}
	} else {
		// 突破失败
		// 损失部分修为
		lossRate := 0.3 // 失败损失30%的突破所需修为
		loss := int64(float64(requiredCultivation) * lossRate)
		user.Cultivation -= loss

		return &RealmBreakthroughResult{
			Success:       false,
			NewRealm:      user.Realm,
			NewRealmLevel: user.RealmLevel,
			Message:       "突破失败，损失了部分修为，但不要气馁，继续努力！",
		}
	}
}

// boostAttributesAfterBreakthrough 突破后提升属性
func (s *gameService) boostAttributesAfterBreakthrough(user *model.User) {
	// 根据突破的境界类型，提升不同的属性
	baseBoost := 20

	// 提升基础属性
	user.HP += int64(baseBoost)
	user.Attack += int64(baseBoost / 2)
	user.Defense += int64(baseBoost / 4)
	user.Speed += int64(baseBoost / 4)

	// 提升寿元
	user.Lifespan += int64(baseBoost * 10)

	// 大境界突破时获得额外奖励
	switch user.Realm {
	case "筑基期":
		user.Talent += baseBoost / 10
	case "结丹期":
		user.Comprehension += baseBoost / 10
	case "元婴期":
		user.Luck += baseBoost / 10
	case "化神期":
		user.Talent += baseBoost / 10
	case "炼虚期":
		user.Comprehension += baseBoost / 10
	case "合体期":
		user.Luck += baseBoost / 10
	case "大乘期":
		user.Talent += baseBoost / 10
	case "渡劫期":
		user.Comprehension += baseBoost / 10
	case "飞升期":
		user.Luck += baseBoost / 10
	}
}